#pragma once

#include <vector>
#include <map>
#include <list>
#include <algorithm>
#include <assert.h>
#include <string>
#include <cstdio>
#include <cwchar>
#include <cfloat>
#include "platform.h"

#ifndef interface
#define interface struct
#endif

#undef SYS_API
#ifdef SYS_DLL
#define SYS_API EXPORT_API
#else
#define SYS_API IMPORT_API
#endif

#ifndef ASSERT	
#define ASSERT		assert
#endif

#ifndef VERIFY
	#ifndef _DEBUG
		#define VERIFY(pred)	pred;
	#else
		#define VERIFY(pred)	assert(pred);
	#endif
#endif

#ifndef VRVERIFY
	#ifndef _DEBUG
		#define VRVERIFY(vr)	vr;
	#else
		#define VRVERIFY(vr)	assert(vr==vok);
	#endif
#endif

#ifndef NULL
#define NULL		0
#endif

#ifndef DECLARE_CONST
#define DECLARE_CONST(type,name,value) \
	const type name = (type)value;
#endif//DECLARE_CONST

#ifndef MAKE_CLSID
#define MAKE_CLSID(moduleID,clsIDOffset) (static_cast<vclsid>((moduleID)+(clsIDOffset)) )
#endif

#ifndef MAKE_IID
#define MAKE_IID(moduleID,iivOffset) (static_cast<viid>((moduleID)+(iivOffset)) )
#endif

#ifndef DEFINE_IID
#define DEFINE_IID(iid) enum{IID_IF=(iid) };
#endif

#ifndef DEFINE_CLSID
#define DEFINE_CLSID(clsID)	enum{CLSID_CLS=(clsID) };
#endif

#ifndef ISSUCCEEDED
#define ISSUCCEEDED(result) (result==vok)
#endif

#ifndef ISFAILED
#define ISFAILED(result) (result!=vok)
#endif

#ifndef DECLARE_TYPE
#define DECLARE_TYPE(orgin,alias) \
	typedef orgin alias;
#endif//DECLARE_TYPE

#ifndef DECLARE_TYPE_map
#define DECLARE_TYPE_map(first,second,alias) \
	typedef std::map<first,second> alias;
#endif//DECLARE_TYPE

#ifndef property_declare
#define property_declare(type,name,id) \
	enum {name = id}; \
	virtual type get##name() const = 0;\
	virtual void set##name(type value) = 0;
#endif

#ifndef property_implement
#define property_implement(type,name,id) \
	private:type m_##name;\
	public:virtual type get##name() const {return m_##name;}\
	public:virtual void set##name(type value) {\
	if (PropertyChanging())	PropertyChanging()(id,GetID(),Self());\
	m_##name = value;\
	if (PropertyChanged())		PropertyChanged()(id,GetID(),Self());\
	}
#endif

#ifndef property_implement_ex
#define property_implement_ex(store_type,type,name,id) \
	private:store_type m_##name;\
	public:virtual type get##name() const {return m_##name;}\
	public:virtual void set##name(type value) {\
	if (PropertyChanging())	PropertyChanging()(id,GetID(),Self());\
	m_##name = value;\
	if (PropertyChanged())		PropertyChanged()(id,GetID(),Self());\
	}
#endif

interface IObject;
DECLARE_TYPE(unsigned char,											byte)
DECLARE_TYPE(unsigned short,										uint16)
DECLARE_TYPE(short,															int16)
DECLARE_TYPE(int,																int32)
DECLARE_TYPE(unsigned int,												uint32)
DECLARE_TYPE(unsigned long,											ulong)
DECLARE_TYPE(wchar_t,														vchar)
DECLARE_TYPE(long	,															vclsid)
DECLARE_TYPE(long	,															viid)
DECLARE_TYPE(long	,															spacid)
DECLARE_TYPE(long	,															moduleid)
DECLARE_TYPE(uint32	,														vresult)
DECLARE_TYPE(uint32	,														objectid)
DECLARE_TYPE(byte*,															vstr)
DECLARE_TYPE(float,															real4)
DECLARE_TYPE(double,														real8)
DECLARE_TYPE(real4,															real)
DECLARE_TYPE(ulong,														uintptr)
DECLARE_TYPE(std::vector<objectid>,							objectidarray)
DECLARE_TYPE(std::vector<IObject*>,							objectarray)
DECLARE_TYPE_map(objectid, objectid,							objectidmap)

DECLARE_CONST(vclsid,					CLASSID_NULL,								0);
DECLARE_CONST(viid,						INTERFACEID_NULL,					0);
DECLARE_CONST(objectid,				OBJID_NULL,									0);
DECLARE_CONST(objectid,				OBJID_ROOT,									0x80000000);

DECLARE_CONST(real4,					MAX_REAL4,									FLT_MAX);
DECLARE_CONST(real8,					MAX_REAL8,									DBL_MAX);
DECLARE_CONST(real,						MAX_REAL,										MAX_REAL4);
DECLARE_CONST(real4,					MIN_REAL4,									FLT_MIN);
DECLARE_CONST(real8,					MIN_REAL8,									DBL_MIN);
DECLARE_CONST(real,						MIN_REAL,										MIN_REAL4);

#include "macro.h"
#include "delegate"
#include "string.h"